﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace BorgExt
{
    public class BehaviorCollection : ICollection<IBehavior>
    {
        public IBehavior[] Behaviors { get; private set; }

        private GenericParameterHandler<IBehavior> OnAdded { get; set; }

        private GenericParameterHandler<IBehavior> OnRemoved { get; set; }

        public int Count
        {
            get { return Behaviors.Length; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        internal BehaviorCollection(GenericParameterHandler<IBehavior> onAdded,
            GenericParameterHandler<IBehavior> onRemoved)
        {
            Behaviors = new IBehavior[0];
            OnAdded = onAdded;
            OnRemoved = onRemoved;
        }

        public void Add(IBehavior behavior)
        {
            if (behavior == null)
                throw new ArgumentNullException("behavior");
            
            Behaviors = ArrayEx.Add(Behaviors, behavior);
            OnAdded(behavior);
        }

        public void Clear()
        {
            var behaviors = Behaviors;
            Behaviors = new IBehavior[0];
            
            foreach (var args in behaviors)
                OnRemoved(args);
        }

        public bool Contains(IBehavior behavior)
        {
            if (behavior == null)
                throw new ArgumentNullException("behavior");
            
            return Array.Exists(Behaviors, item => item.Equals(behavior));
        }

        public void CopyTo(IBehavior[] behaviors, int arrayIndex)
        {
            Array.Copy(Behaviors, 0, behaviors, arrayIndex, Behaviors.Length);
        }

        public bool Remove(IBehavior behavior)
        {
            if (behavior == null)
                throw new ArgumentNullException("behavior");

            var length = Behaviors.Length;
            Behaviors = ArrayEx.Remove(Behaviors, behavior);
            
            if (Behaviors.Length >= length)
                return false;

            OnRemoved(behavior);
            
            return true;
        }

        public IEnumerator<IBehavior> GetEnumerator()
        {
            return ((IEnumerable<IBehavior>)Behaviors).GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}

